package yxy.game.pm2.module.hero;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import net.bytebuddy.implementation.bytecode.Throw;
import org.apache.commons.lang3.StringUtils;
import yxy.apple.logger.Logger;
import yxy.apple.util.concurrent.ThreadPoolManager;
import yxy.apple.util.redisson.RedisException;
import yxy.cherry.battle.Battle;
import yxy.cherry.battle.module.Position;
import yxy.cherry.battle.module.PropertyData;
import yxy.cherry.battle.module.PropertyType;
import yxy.cherry.data.DataCenter;
import yxy.cherry.data.bean.*;
import yxy.cherry.data.function.Function;
import yxy.cherry.data.script.fomula;
import yxy.cherry.data.string.GameString;
import yxy.cherry.game.base.message.MessageEmitterHandler;
import yxy.cherry.game.base.message.annotation.MessageSource;
import yxy.game.pm2.Result;
import yxy.game.pm2.bean.Currency;
import yxy.game.pm2.bean.*;
import yxy.game.pm2.bean.Format.FormatType;
import yxy.game.pm2.bean.currency.Currencies;
import yxy.game.pm2.bean.currency.CurrencyNotEnoughException;
import yxy.game.pm2.bean.currency.CurrencyType;
import yxy.game.pm2.bean.module.rank.openserviceactive.OpenServiceRushRankEnum;
import yxy.game.pm2.bean.module.rank.openserviceactive.OpenServiceRushRankHandle;
import yxy.game.pm2.bean.module.rank.openserviceactive.herolevelrushrank.OpenServiceHeroLevelRushRank;
import yxy.game.pm2.bean.mq.CCReason;
import yxy.game.pm2.bean.pubsub.HeroPackPublisher;
import yxy.game.pm2.bean.reset.BattleClear;
import yxy.game.pm2.bean.reset.StageReset;
import yxy.game.pm2.bean.reset.StartReset;
import yxy.game.pm2.bean.task.TaskType;
import yxy.game.pm2.message.AltarMessage;
import yxy.game.pm2.message.HeroMessage;
import yxy.game.pm2.message.PlayerMessage;
import yxy.game.pm2.message.TempleMessage;
import yxy.game.pm2.module.CurrencyHandle;
import yxy.game.pm2.module.NotificationHandle;
import yxy.game.pm2.module.PackageHandle;
import yxy.game.pm2.module.active.openservicerush.OpenServiceRushRecord;
import yxy.game.pm2.module.battle.BattleHandle;
import yxy.game.pm2.module.player.FunctionHandle;
import yxy.game.pm2.module.playtype.PlayTypeModule;
import yxy.game.pm2.module.resonate.ResonateHandle;
import yxy.game.pm2.module.task.TaskHandle;
import yxy.game.pm2.module.temple.TempleHandle;
import yxy.game.pm2.module.tip.TipHandle;
import yxy.game.pm2.module.tip.TipType;
import yxy.game.pm2.module.union.UnionHandle;
import yxy.game.pm2.module.union.UnionHandle.UnionPlayerEntry;
import yxy.game.pm2.module.union.player.tech.UnionPlayerTech;
import yxy.game.pm2.module.union.player.tech.UnionTech;

import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.CopyOnWriteArraySet;

public class HeroHandle {

    private static Logger logger = Logger.create(HeroHandle.class);

    /**
     * 布阵页面获取上阵武将的总战力
     *
     * @param playerCode
     */
    public JSONArray getAllPower(String playerCode, Map<Position, Hero> map, Format format, int formatType) {
        JSONArray jsonArray = new JSONArray();//  [{'code':'','power':''},{'code':'','power':''} ]
        try {
            BattleHandle battleHandle = new BattleHandle();
            //计算队伍的战力
            if (format.getIsAfreshPower() != formatType) {
                for (Entry<Position, Hero> entry : map.entrySet()) {
                    JSONObject heroJson = new JSONObject();
                    Hero hero = entry.getValue();
                    long power = battleHandle.calculatePower(playerCode, hero, format);
                    heroJson.put(hero.getCode(), power);
                    jsonArray.add(heroJson);
                }
                format.setIsAfreshPower(1);
                Format.set(playerCode, FormatType.普通, format);
            } else {
                for (Entry<Position, Hero> entry : map.entrySet()) {
                    JSONObject heroJson = new JSONObject();
                    Hero hero = entry.getValue();
                    long power = hero.getPower();
                    heroJson.put(hero.getCode(), power);
                    jsonArray.add(heroJson);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return jsonArray;
    }


    /**
     * 布阵保存获取队伍总战力
     *
     * @param heros
     * @param isChange
     * @return
     */
    public long getAllPower(Collection<Hero> heros, Format format, String playerCode, int afreshPowerType, Boolean isChange) {
        Long allPower = 0l;
        try {
            //计算队伍的战力
            if (format.getIsAfreshPower() != afreshPowerType || isChange) {
                BattleHandle battleHandle = new BattleHandle();
                for (Hero hero : heros) {
                    allPower += battleHandle.calculatePower(playerCode, hero, format);
                }
                format.setIsAfreshPower(1);
                Format.set(playerCode, FormatType.普通, format);
            } else {
                for (Hero hero : heros) {
                    Long power = hero.getPower();
                    allPower += power;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return allPower;
    }


    /**
     * 获取自由身武将
     */
    public Map<String, Hero> getFreeHeros(String playerCode) {
        FormatHandle formatHandle = new FormatHandle();
        Map<String, Hero> result = new HashMap<>();
        for (Hero hero : getHeros(playerCode)) {
            if (hero.isLock() || formatHandle.heroInFormat(playerCode, hero.getCode())) {
                continue;
            }
            result.put(hero.getCode(), hero);
        }
        return result;
    }

    public Collection<Hero> getHeros(String playerCode) {
        //按等级排序
        Map<String, Hero> all = Hero.all(playerCode);
        LinkedHashMap<String, Hero> linkedHashMap = new LinkedHashMap<>();
        ArrayList<Hero> heroList = new ArrayList<>();

        for (Entry<String, Hero> entry : all.entrySet()) {
            heroList.add(entry.getValue());
        }

        Collections.sort(heroList, new Comparator<Object>() {
            @Override
            public int compare(Object o1, Object o2) {
                Hero hero1 = (Hero) o1;
                Hero hero2 = (Hero) o2;
                return hero2.getLevel() - hero1.getLevel();
            }
        });

        for (int i = 0; i < heroList.size(); i++) {
            linkedHashMap.put(i + "", heroList.get(i));
        }
        return linkedHashMap.values();
    }

    public int getHerosSize(String playerCode) {
        return Hero.size(playerCode);
    }

    public int getUpper(String playerCode) {
        HeroModule heroModule = HeroModule.get(playerCode);
        return heroModule.getHeroPackUpper();
    }

    public int buyUpper(HeroModule heroModule) {
        int buyUpper = fomula.武将背包每次增长个数.intValue();

        int times = heroModule.getHeroPackUpperBuyTimes();
        int upper = heroModule.getHeroPackUpper();
        heroModule.setHeroPackUpperBuyTimes(times + 1);
        heroModule.setHeroPackUpper(upper + buyUpper);
        heroModule.set();

        return heroModule.getHeroPackUpper();
    }

    /**
     * 判断背包数量已达上限
     */
    public boolean isUpper(HeroModule heroModule) {
        int baseUpper = fomula.武将背包上限初始.intValue();
        return heroModule.getHeroPackUpper() >= baseUpper + vipUpper(heroModule.getPlayerCode());
    }

    private int vipUpper(String playerCode) {
        PlayerBean playerBean = PlayerBean.get(playerCode);
        int viplevel = playerBean.getViplevel();
        vipdata _vipdata = DataCenter.getData(viplevel, vipdata.class);
        if (_vipdata == null) {
            return 0;
        }
        return _vipdata.getVar6();
    }

    public Hero getHero(String playerCode, String code) {
        Hero hero = Hero.get(playerCode, code);
        return hero;
    }

    public boolean updateHero(String playerCode, Hero hero) {
        boolean result = Hero.set(playerCode, hero);
        // 推送战力变化
        Runnable runnable = () -> new BattleHandle().heroUpdate(playerCode, hero);
        ThreadPoolManager.getInstance().execute(runnable);
        return result;
    }


    public Collection<HeroMessage.HeroSimple> packHeros(String playerCode) {
        // TODO 需要优化
        return null;
    }

    public HeroMessage.HeroSimple getHeroSimple(String playerCode, Hero hero) {
        return getHeroSimple(playerCode, hero, 0);
    }

    public HeroMessage.HeroSimple getHeroSimpleWithPower(String playerCode, Hero hero) {
        return getHeroSimple(playerCode, hero, new BattleHandle().power(playerCode, hero));
    }

    public HeroMessage.HeroSimple getHeroSimple(String playerCode, Hero hero, long power) {
        HeroMessage.HeroSimple.Builder builder = HeroMessage.HeroSimple.newBuilder();
        builder.setCode(hero.getCode());
        builder.setDataId(hero.getDataId());
        builder.setLevel(hero.getLevel());
        builder.setStar(hero.getStar());
        builder.setLock(hero.isLock());
        builder.setBattlepower(power);
        //资质返回
        herodata data = DataCenter.getData(hero.getDataId(), herodata.class);
        builder.setAptitude(data.getAptitude());
        builder.setDuty(new FormatHandle().heroInFormat(playerCode, hero.getCode()));
        return builder.build();
    }

    //战力直接从缓存获取
    public HeroMessage.HeroInfo getHeroInfoNoCalculatePower(String playerCode, Hero hero) {

        int levelUpper = levelUpper(hero, playerCode);
        PropertyData propertyData = BattleHandle.packProperty(playerCode, hero);
        long power = new BattleHandle().power(playerCode, hero);

        HeroMessage.HeroInfo.Builder builder = HeroMessage.HeroInfo.newBuilder();
        builder.setBase(getHeroSimple(playerCode, hero, power));
        builder.setLevelUpper(levelUpper);
        builder.setStage(hero.getStage());
        for (int i = 0; i < hero.getEquips().length; i++) {
            builder.addEquips(hero.getEquips()[i]);
        }

        builder.setProperty(getHeroProperty(propertyData));

        // 魂玉
        if (hero.getSoulA() != null) {
            builder.setSoulA(packSoul(playerCode, hero.getSoulA()));
        }
        if (hero.getSoulB() != null) {
            builder.setSoulB(packSoul(playerCode, hero.getSoulB()));
        }

        // 兵法
        try {
            if (hero.getMagicA() != null) {
                builder.setMagicA(Integer.valueOf(hero.getMagicA()));
            }
            if (hero.getMagicB() != null) {
                builder.setMagicB(Integer.valueOf(hero.getMagicB()));
            }
            if (hero.getMagicC() != null) {
                builder.setMagicB(Integer.valueOf(hero.getMagicC()));
            }
        } catch (NumberFormatException e) {
        }

        // 联盟科技等级
        int unionTechLevel = -1;
        UnionPlayerEntry entry = new UnionPlayerEntry(playerCode);
        Result result = new UnionHandle().checkPlayerUnion(entry);
        if (result.equals(Result.UnionIn)) {
            herodata data = DataCenter.getData(hero.getDataId(), herodata.class);
            UnionPlayerTech playerTech = entry.getUnionPlayer().getTech();
            for (UnionTech tech : playerTech.getTechList()) {
                if (tech.data().getType() == data.getHerotype()) {
                    unionTechLevel = tech.getLevel();
                    break;
                }
            }
        }
        builder.setUniontech(unionTechLevel);

        // XXX 圣器等级
        builder.setPyx(0);

        return builder.build();
    }


    public HeroMessage.HeroInfo getHeroInfo(String playerCode, Hero hero) {
        int levelUpper = levelUpper(hero, playerCode);
        PropertyData propertyData = BattleHandle.packProperty(playerCode, hero);

        long power = new BattleHandle().power(playerCode, hero);

        HeroMessage.HeroInfo.Builder builder = HeroMessage.HeroInfo.newBuilder();
        builder.setBase(getHeroSimple(playerCode, hero, power));
        builder.setLevelUpper(levelUpper);
        builder.setStage(hero.getStage());
        for (int i = 0; i < hero.getEquips().length; i++) {
            builder.addEquips(hero.getEquips()[i]);
        }

        builder.setProperty(getHeroProperty(propertyData));

        // 魂玉
        if (hero.getSoulA() != null) {
            builder.setSoulA(packSoul(playerCode, hero.getSoulA()));
        }
        if (hero.getSoulB() != null) {
            builder.setSoulB(packSoul(playerCode, hero.getSoulB()));
        }

        // 兵法
        try {
            if (hero.getMagicA() != null) {
                builder.setMagicA(Integer.valueOf(hero.getMagicA()));
            }
            if (hero.getMagicB() != null) {
                builder.setMagicB(Integer.valueOf(hero.getMagicB()));
            }
            if (hero.getMagicC() != null) {
                builder.setMagicB(Integer.valueOf(hero.getMagicC()));
            }
        } catch (NumberFormatException e) {
        }

        // 联盟科技等级
        int unionTechLevel = -1;
        UnionPlayerEntry entry = new UnionPlayerEntry(playerCode);
        Result result = new UnionHandle().checkPlayerUnion(entry);
        if (result.equals(Result.UnionIn)) {
            herodata data = DataCenter.getData(hero.getDataId(), herodata.class);
            UnionPlayerTech playerTech = entry.getUnionPlayer().getTech();
            for (UnionTech tech : playerTech.getTechList()) {
                if (tech.data().getType() == data.getHerotype()) {
                    unionTechLevel = tech.getLevel();
                    break;
                }
            }
        }
        builder.setUniontech(unionTechLevel);

        // XXX 圣器等级
        builder.setPyx(0);

        return builder.build();
    }


    public int levelUpper(Hero hero, String playerCode) {
        herostagecost _herostagecost = DataCenter.getData(hero.getStage(), herostagecost.class);
        heroadvanced _heroadvanced = DataCenter.getData(hero.advancedCode(), heroadvanced.class);
        if (_heroadvanced == null || _herostagecost == null) {
            throw new NullPointerException("playerCode:" + playerCode + "------hero.advancedCode():" + hero.advancedCode() + "------hero.getStage():" + hero.getStage());
        }

        //当前星级武将的最高等级
        int herolvup = _heroadvanced.getHerolvup();
        //升阶需要的等级
        int levelup = _herostagecost.getCondition();
        return levelup > herolvup ? levelup : herolvup;
    }

    private HeroMessage.Soul packSoul(String playerCode, String code) {
        Soul soul = Soul.get(playerCode, code);
        if (soul == null) {
            return null;
        }
        return packSoul(soul);
    }

    private HeroMessage.Soul packSoul(Soul soul) {
        HeroMessage.Soul.Builder builder = HeroMessage.Soul.newBuilder();
        builder.setCode(soul.getCode());
        builder.setDataId(soul.getDataId());
        for (Integer id : soul.getPropertyIds()) {
            builder.addProperty(id);
        }
        for (Integer id : soul.getSkillIds()) {
            builder.addSkill(id);
        }
        return builder.build();
    }

    public HeroMessage.HeroProperty getHeroProperty(String playerCode, Hero hero) throws Exception {
        PropertyData propertyData = BattleHandle.packProperty(playerCode, hero);
        return getHeroProperty(propertyData);
    }

    public HeroMessage.HeroProperty getHeroProperty(PropertyData propertyData) {
        HeroMessage.HeroProperty.Builder builder = HeroMessage.HeroProperty.newBuilder();
        builder.setAtt(propertyData.getValue(PropertyType.P_攻击));
        builder.setPdef(propertyData.getValue(PropertyType.P_防御));
        builder.setSefe(propertyData.getValue(PropertyType.P_法防));
        builder.setLife(propertyData.getValue(PropertyType.P_生命));
        builder.setStr(propertyData.getValue(PropertyType.P_暴击));
        builder.setAnt(propertyData.getValue(PropertyType.P_抗暴));
        builder.setBus(propertyData.getValue(PropertyType.P_暴伤));
        builder.setBud(propertyData.getValue(PropertyType.P_韧性));
        builder.setFit(propertyData.getValue(PropertyType.P_命中));
        builder.setDog(propertyData.getValue(PropertyType.P_闪避));
        builder.setCtl(propertyData.getValue(PropertyType.P_控制));
        builder.setRss(propertyData.getValue(PropertyType.P_抗控));
        builder.setTre(propertyData.getValue(PropertyType.P_治疗));
        builder.setTrp(propertyData.getValue(PropertyType.P_受疗));
        builder.setPdefup(propertyData.getValue(PropertyType.P_增伤));
        builder.setSefeup(propertyData.getValue(PropertyType.P_法增));
        builder.setPdefgd(propertyData.getValue(PropertyType.P_减伤));
        builder.setSefegd(propertyData.getValue(PropertyType.P_法减));
        builder.setSpeed(propertyData.getValue(PropertyType.P_速度));
        return builder.build();
    }

    private PropertyData getPropertyModule(JSONObject propertyModule) {
        PropertyData propertyData = new PropertyData();
        propertyData.setValue(PropertyType.P_攻击, propertyModule.getLongValue("att"));
        propertyData.setValue(PropertyType.P_防御, propertyModule.getLongValue("pdef"));
        propertyData.setValue(PropertyType.P_法防, propertyModule.getLongValue("sefe"));
        propertyData.setValue(PropertyType.P_生命, propertyModule.getLongValue("life"));
        propertyData.setValue(PropertyType.P_暴击, propertyModule.getLongValue("str"));
        propertyData.setValue(PropertyType.P_抗暴, propertyModule.getLongValue("ant"));
        propertyData.setValue(PropertyType.P_暴伤, propertyModule.getLongValue("bus"));
        propertyData.setValue(PropertyType.P_韧性, propertyModule.getLongValue("bud"));
        propertyData.setValue(PropertyType.P_命中, propertyModule.getLongValue("fit"));
        propertyData.setValue(PropertyType.P_闪避, propertyModule.getLongValue("dog"));
        propertyData.setValue(PropertyType.P_控制, propertyModule.getLongValue("ctl"));
        propertyData.setValue(PropertyType.P_抗控, propertyModule.getLongValue("rss"));
        propertyData.setValue(PropertyType.P_治疗, propertyModule.getLongValue("tre"));
        propertyData.setValue(PropertyType.P_受疗, propertyModule.getLongValue("trp"));
        propertyData.setValue(PropertyType.P_增伤, propertyModule.getLongValue("pdefup"));
        propertyData.setValue(PropertyType.P_法增, propertyModule.getLongValue("sefeup"));
        propertyData.setValue(PropertyType.P_减伤, propertyModule.getLongValue("pdefgd"));
        propertyData.setValue(PropertyType.P_法减, propertyModule.getLongValue("sefegd"));
        propertyData.setValue(PropertyType.P_速度, propertyModule.getLongValue("speed"));

        return propertyData;
    }


    /**
     * 无消耗升级
     *
     * @param playerCode
     * @param hero        目标英雄
     * @param targetLevel 目标等级
     * @return
     */
    public Result noConsumptionLevelUp(String playerCode, Hero hero, int targetLevel) {
        //System.out.println("进入无消耗升级 ");
        Hero hero1 = hero;
        int targetLevel1 = targetLevel;
        int levelUpper = levelUpper(hero1, playerCode);        //英雄当前星级的等级上线
        if (hero.getLevel() >= targetLevel1) {        //英雄当前等级大于等于目标等级，不做操作
            return Result.Success;
        }


        while (true) {
            if (levelUpper < targetLevel1) {                //目标等级大于等级上限，将英雄升星
                Hero hero2 = noConsumptionStarUp(playerCode, hero1);
                if (hero2 == null) {                        //英雄已经达到最高星级
                    targetLevel1 = levelUpper(hero1, playerCode);        //修改目标等级为当前等级上限
                    break;
                } else {
                    hero1 = hero2;
                }
                levelUpper = levelUpper(hero1, playerCode);
            } else {
                break;
            }
        }


        while (true) {
            if (targetLevel1 - hero1.getLevel() > 5) {    //目标等级与当前等级相差大于5，英雄等级+5
                hero1.setLevel(hero1.getLevel() + 5);
                updateHero(playerCode, hero1);
            } else {                                    //目标等级与当前等级相差小于5，英雄等级提升到目标等级
                hero1.setLevel(targetLevel1);
                updateHero(playerCode, hero1);
                noConsumptionStageUp(playerCode, hero1);    //尝试无消耗升阶
                break;
            }

            hero1 = noConsumptionStageUp(playerCode, hero1);    //尝试无消耗升阶
        }

        return Result.Success;
    }

    /**
     * 无消耗升阶
     *
     * @param playerCode
     * @param hero       目标英雄
     * @return true升阶成功，false升阶失败
     */
    protected Hero noConsumptionStageUp(String playerCode, Hero hero) {
        //System.out.println("进入无消耗升阶");
        herostagecost _herostagecost = DataCenter.getData(hero.getStage(), herostagecost.class);
        int levelUpper = _herostagecost.getCondition();
        if (hero.getLevel() < levelUpper) {
            return hero; // 等级不够
        }
        herograde grade = DataCenter.getData(hero.getDataId(), herograde.class);
        int stagemax = grade.getStagemax();// 升阶上限
        if (hero.getStage() >= stagemax) {
            return hero;// 升阶已满
        }

        hero.setStage(hero.getStage() + 1);
        updateHero(playerCode, hero);

        return hero;
    }

    /**
     * 无消耗升星
     *
     * @param playerCode
     * @param hero       目标英雄
     * @return
     */
    public Hero noConsumptionStarUp(String playerCode, Hero hero) {
        System.out.println("进入无消耗升星");
        int nextStar = hero.getStar() + 1;
        int nextId = hero.getDataId();
        heroadvanceddata advanceddata = DataCenter.getData(hero.getDataId(), heroadvanceddata.class);
        if (nextStar > advanceddata.getStartop()) {
            // 到达升级上限
            if (advanceddata.getEvolutionid() <= 0) {
                return null; // 星级已满
            }
            nextId = advanceddata.getEvolutionid();
        }
        heroadvanced nextadvanced = DataCenter.getData(String.format("%d_%d", nextId, nextStar), heroadvanced.class);
        if (nextadvanced == null) {
            return null; // 星级已满
        }

        Currencies heroCosts = new Currencies();
        hero.setDataId(nextId);
        hero.setStar(nextStar);
        hero.getStarUpCost().addFirst(heroCosts);
        updateHero(playerCode, hero);
        return hero;
    }

    /**
     * 武将升级
     */
    public Result levelUp(String playerCode, Hero hero, int times) {

        int levelUpper = levelUpper(hero, playerCode);
        System.out.println("当前等级上限：" + levelUpper);
        if (hero.getLevel() >= levelUpper) {
            return Result.HeroLevelUpper;// 等级已到最高
        }
        if (hero.getLevel() + times > levelUpper) {
            return Result.ParamError;// 升级次数超上限了
//			times = levelUpper-hero.getLevel();//自修正
        }
        int level = hero.getLevel();
        Collection<Currency> cost = levelUpCost(hero, times);
        try {
            new CurrencyHandle().cost(playerCode, CCReason.武将培养, cost);
        } catch (CurrencyNotEnoughException e) {
            return new Result(Result.CostFail, e.getType().getNumber(), e.getDataId());// 消费不足
        }

        hero.setLevel(hero.getLevel() + times);

        boolean success = updateHero(playerCode, hero);
        if (!success) {
            return Result.DataError;
        }

        Runnable runnable = () -> {
            for (int i = level; i < hero.getLevel(); i++) {
                TaskHandle.handle(playerCode, TaskType.统计型_武将_等级_累计_达到, 1, i);
            }
        };
        ThreadPoolManager.getInstance().execute(runnable);
        /**
         * 开服冲榜-统计x资质的武将的等级
         */
        Runnable runnableB = () -> {
            herodata data = DataCenter.getData(hero.getDataId(), herodata.class);
            int aptitude = data.getAptitude();//资质
            int openrushlevel = hero.getLevel();//等级
            int[] ints = OpenServiceHeroLevelRushRank.updateHeroLevelRanking(
                    playerCode,
                    aptitude,
                    openrushlevel,
                    OpenServiceRushRankEnum.开服冲榜_等级提升.getType());
            if (ints[2] != -1) {
                OpenServiceRushRecord.recordFirstCompleteHeroLevelTask(playerCode, ints[1], ints[0]);
            }
        };
        ThreadPoolManager.getInstance().execute(runnableB);
        return Result.Success;
    }

    public Collection<Currency> levelUpCost(Hero hero, int times) {
        return Hero.levelUpCost(hero.getLevel(), hero.getLevel() + times);
    }

    /**
     * 武将升阶
     */
    public Result stageUp(String playerCode, Hero hero) {
        herostagecost _herostagecost = DataCenter.getData(hero.getStage(), herostagecost.class);
        int levelUpper = _herostagecost.getCondition();
        if (hero.getLevel() < levelUpper) {
            return Result.HeroLevelLack; // 等级不够
        }
        herograde grade = DataCenter.getData(hero.getDataId(), herograde.class);
        int stagemax = grade.getStagemax();// 升阶上限
        if (hero.getStage() >= stagemax) {
            return Result.HeroStageUpper;// 升阶已满
        }

        //升阶需判断武将星级、背包中其他武将等级和数量
        Map<String, Hero> all = Hero.all(playerCode);
        HashMap<String, Integer> map = checkHeroStageUp(_herostagecost, all, hero);
        if (map.get("heroNum") < map.get("needNumber") || map.get("heroStar") < map.get("starCondition")) {
            return Result.HeroStageFail;
        }

        Collection<Currency> cost = Currency.create(_herostagecost.getCosttype(), _herostagecost.getCostid(), _herostagecost.getCostnum());
        try {
            new CurrencyHandle().cost(playerCode, CCReason.武将培养, cost);
        } catch (CurrencyNotEnoughException e) {
            return new Result(Result.CostFail, e.getType().getNumber(), e.getDataId());// 消费不足
        }
        hero.setStage(hero.getStage() + 1);
        boolean success = updateHero(playerCode, hero);
        if (!success) {
            return Result.DataError;
        }
        return Result.Success;
    }

    private HashMap<String, Integer> checkHeroStageUp(herostagecost herostagecost, Map<String, Hero> heroMap, Hero hero) {
        HashMap<String, Integer> map = new HashMap<>();
        //获取当前武将升阶的的阵容要求
        int starCondition = herostagecost.getStarCondition(); //星级条件
        int needLevel = herostagecost.getNeedLevel(); //其他武将等级
        int needNumber = herostagecost.getNeedNumber(); //其他武将数量

        Iterator<Entry<String, Hero>> iterator = heroMap.entrySet().iterator();
        int heroNum = 0;//满足的英雄数量

        while (iterator.hasNext() && needNumber != 0) {
            Entry<String, Hero> next = iterator.next();
            Hero heroEntry = next.getValue();

            if (heroEntry.getLevel() < needLevel) {
                continue;
            }

            if (heroNum >= needNumber) {
                break;
            }
            heroNum++;
        }

        map.put("starCondition", starCondition);
        map.put("needLevel", needLevel);
        map.put("needNumber", needNumber);
        map.put("heroNum", heroNum);
        map.put("heroStar", hero.getStar());
        return map;
    }

    /**
     * 武将升星
     */
    public Result starUp(String playerCode, Hero hero, Set<String> expend, HeroMessage.HeroStarUpResponse.Builder response) {
        if (expend.contains(hero.getCode())) {
            return Result.HeroStarCantSelf; // 不能消耗自己
        }

        int nextStar = hero.getStar() + 1;
        // function检查
        switch (nextStar) {
            case 11:
                if (!new FunctionHandle().check(Function.武将升11星, playerCode)) {
                    return Result.ModuleNotOpen;
                }
                break;
            case 12:
                if (!new FunctionHandle().check(Function.武将升12星, playerCode)) {
                    return Result.ModuleNotOpen;
                }
                break;
            case 13:
                if (!new FunctionHandle().check(Function.武将升13星, playerCode)) {
                    return Result.ModuleNotOpen;
                }
                break;
            case 14:
                if (!new FunctionHandle().check(Function.武将升14星, playerCode)) {
                    return Result.ModuleNotOpen;
                }
                break;
            case 15:
                if (!new FunctionHandle().check(Function.武将升15星, playerCode)) {
                    return Result.ModuleNotOpen;
                }
                break;
        }

        int nextId = hero.getDataId();
        heroadvanceddata advanceddata = DataCenter.getData(hero.getDataId(), heroadvanceddata.class);
        if (nextStar > advanceddata.getStartop()) {
            // 到达升级上限
            if (advanceddata.getEvolutionid() <= 0) {
                return Result.HeroStarUpper; // 星级已满
            }
            nextId = advanceddata.getEvolutionid();
        }
        heroadvanced nextadvanced = DataCenter.getData(String.format("%d_%d", nextId, nextStar), heroadvanced.class);
        if (nextadvanced == null) {
            return Result.HeroStarUpper; // 星级已满
        }

        Currencies heroCosts = new Currencies();
        Result result = starUpCost(playerCode, hero, expend, heroCosts, response);
        if (!result.equals(Result.Success)) {
            return result;
        }

        hero.setDataId(nextId);
        hero.setStar(nextStar);
        hero.getStarUpCost().addFirst(heroCosts);
        boolean success = updateHero(playerCode, hero);
        if (!success) {
            return Result.HeroStarFail;
        }

        response.setInfo(getHeroInfo(playerCode, hero));
        Runnable runnable = () -> {
            TaskHandle.handle(playerCode, TaskType.统计型_武将_星级_个数, 1, hero.getStar());
            TaskHandle.handle(playerCode, TaskType.统计型_武将_合成_星级_个数, 1, hero.getStar());
            // 滚屏消息
            PlayerBean playerBean = PlayerBean.get(playerCode);
            new NotificationHandle().notifyChatInner(playerCode, GameString.将武将星级升至(playerBean.getName(), nextadvanced.getName(), nextStar));
        };
        ThreadPoolManager.getInstance().execute(runnable);
        return Result.Success;
    }

    private Result starUpCost(String playerCode, Hero hero, Set<String> expend, Currencies heroCosts, HeroMessage.HeroStarUpResponse.Builder response) {
        heroadvanced advanced = DataCenter.getData(hero.advancedCode(), heroadvanced.class);
        CopyOnWriteArraySet<String> expendSet = new CopyOnWriteArraySet<>(expend);
        Map<String, Hero> heros = getFreeHeros(playerCode);
        HashMap<String, Hero> expendhero = new HashMap<>();
        Currencies costs = new Currencies();
        for (int i = 0; i < advanced.getConditiontype().length; i++) {
            int conditionType = advanced.getConditiontype()[i];
            int cost1 = advanced.getCost1()[i];
            int cost2 = advanced.getCost2()[i];
            int cost3 = advanced.getCost3()[i];
            switch (conditionType) {
                case 1:// 消耗指定武将
                {
                    int num = 0;
                    for (String code : expendSet) {
                        Hero exhero = heros.get(code);
                        if (exhero == null) {
                            return Result.HeroStarFail; // 武将升星失败
                        }
                        if (exhero.getDataId() == cost1 && exhero.getStar() == cost2) {
                            num++;
                            expendSet.remove(code);
                            expendhero.put(exhero.getCode(), exhero);
                        }
                        if (num >= cost3) {
                            break;
                        }
                    }
                    if (num < cost3) {
                        return Result.HeroStarFail; // 武将升星失败
                    }
                    break;
                }
                default:
                    break;
            }
        }

        for (int i = 0; i < advanced.getConditiontype().length; i++) {
            int conditionType = advanced.getConditiontype()[i];
            int cost1 = advanced.getCost1()[i];
            int cost2 = advanced.getCost2()[i];
            int cost3 = advanced.getCost3()[i];
            switch (conditionType) {
                case 2:// 消耗符合阵营武将
                {
                    int num = 0;
                    for (String code : expendSet) {
                        Hero exhero = heros.get(code);
                        if (exhero == null) {
                            return Result.HeroStarFail; // 武将升星失败
                        }
                        herodata data = DataCenter.getData(exhero.getDataId(), herodata.class);
                        if (data.getPower() == cost1 && exhero.getStar() == cost2) {
                            num++;
                            expendSet.remove(code);
                            expendhero.put(exhero.getCode(), exhero);
                        }
                        if (num >= cost3) {
                            break;
                        }
                    }
                    if (num < cost3) {
                        return Result.HeroStarFail; // 武将升星失败
                    }
                    break;
                }
                case 3:// 任意阵营武将
                {
                    int num = 0;
                    for (String code : expendSet) {
                        Hero exhero = heros.get(code);
                        if (exhero == null) {
                            return Result.HeroStarFail; // 武将升星失败
                        }
                        if (exhero.getStar() == cost2) {
                            num++;
                            expendSet.remove(code);
                            expendhero.put(exhero.getCode(), exhero);
                        }
                        if (num >= cost3) {
                            break;
                        }
                    }
                    if (num < cost3) {
                        return Result.HeroStarFail; // 武将升星失败
                    }
                    break;
                }
                case 4:// 消耗物品
                {
                    Currency cost = Currency.create(cost1, cost2, cost3);
                    costs.add(cost);
                }
                default:
                    break;
            }
        }
        {
            // 升星消耗
            Currency cost = Currency.create(advanced.getCosttype(), advanced.getCostid(), advanced.getCostnum());
            costs.add(cost);
            try {
                new CurrencyHandle().cost(playerCode, CCReason.武将培养, costs);
            } catch (CurrencyNotEnoughException e) {
                return new Result(Result.CostFail, e.getType().getNumber(), e.getDataId());// 消费不足
            }
        }

        HashSet<String> herocodes = new HashSet<>();
        for (Hero h : expendhero.values()) {
            herocodes.add(h.getCode());
            heroCosts.add(Currency.create(CurrencyType.CT_武将, h.getDataId(), h.getStar()));
        }

        // 升星返还
        Collection<Currency> back = expendBackDo(playerCode, expendhero, CCReason.武将培养);
        if (back != null) {
            response.addAllBack(new CurrencyHandle().packItems(back));
        }
        response.addAllExpend(herocodes);
        return Result.Success;
    }

    public Collection<Currency> returnBack(String playerCode, Hero hero) {
        HashMap<String, Hero> map = new HashMap<>();
        map.put(hero.getCode(), hero);
        return returnBack(playerCode, map);
    }

    /**
     * 武将返还
     */
    public Collection<Currency> returnBack(String playerCode, HashMap<String, Hero> heros) {
        Currencies back = new Currencies();
        Currencies soulback = new Currencies();
        for (Hero hero : heros.values()) {
            int[] equips = hero.getEquips();
            for (int i = 0; i < equips.length; i++) {
                if (equips[i] > 0) {
                    back.add(Currency.create(CurrencyType.CT_装备, equips[i], 1));
                }
            }
            if (hero.getSoulA() != null) {
                Soul heroSoul = Soul.get(playerCode, hero.getSoulA());
                if (heroSoul != null) {
                    soulback.add(Currency.create(CurrencyType.CT_魂玉, heroSoul.getDataId(), 1));
                }
            }
            if (hero.getSoulB() != null) {
                Soul heroSoul = Soul.get(playerCode, hero.getSoulB());
                if (heroSoul != null) {
                    soulback.add(Currency.create(CurrencyType.CT_魂玉, heroSoul.getDataId(), 1));
                }
            }
            back.addAll(hero.trainAll());
        }
        if (soulback.size() > 0) {
            back.addAll(soulback);
        }
        return back;
    }

    /**
     * 武将消耗返还
     */
    private Collection<Currency> expendBackDo(String playerCode, HashMap<String, Hero> expendhero, CCReason reason) {
        Currencies back = new Currencies();
        Currencies soulback = new Currencies();
        for (Hero hero : expendhero.values()) {
            int[] equips = hero.getEquips();
            for (int i = 0; i < equips.length; i++) {
                if (equips[i] > 0) {
                    back.add(Currency.create(CurrencyType.CT_装备, equips[i], 1));
                }
            }
            if (hero.getSoulA() != null) {
                Soul heroSoul = Soul.get(playerCode, hero.getSoulA());
                if (heroSoul != null) {
                    hero.setSoulA(null);
                    heroSoul.setHero(null);
                    Soul.set(playerCode, heroSoul);
                    soulback.add(Currency.create(CurrencyType.CT_魂玉, heroSoul.getDataId(), 1));
                }
            }
            if (hero.getSoulB() != null) {
                Soul heroSoul = Soul.get(playerCode, hero.getSoulB());
                if (heroSoul != null) {
                    hero.setSoulB(null);
                    heroSoul.setHero(null);
                    Soul.set(playerCode, heroSoul);
                    soulback.add(Currency.create(CurrencyType.CT_魂玉, heroSoul.getDataId(), 1));
                }
            }
            back.addAll(hero.trainAll());
        }
        Hero.removeHeros(playerCode, expendhero.values(), reason);
        if (back.size() > 0 || soulback.size() > 0) {
            new CurrencyHandle().addCurrency(playerCode, reason, back);
            if (soulback.size() > 0) {
                back.addAll(soulback);
            }
        }
        return back;
    }

    /**
     * 武将换装
     */
    public Result changeEquip(String playerCode, Hero hero, EquipPosition pos, int dataId) throws Exception {
        int backEquipId = hero.getequip(pos);
        if (dataId == backEquipId) {
            return Result.Success;
        }
        if (backEquipId > 0) {
            equipdata _equipdata = DataCenter.getData(backEquipId, equipdata.class);
            if (_equipdata == null) {
                return Result.DataError;
            }
        }
        if (dataId > 0) {
            // 看背包里有没有
            Currency item = Item.get(playerCode, CurrencyType.CT_装备, dataId);
            if (item == null || item.getNumber() < 1) {
                return Result.EquipNotExisted;// 背包里没有这个装备
            }
            Item.minus(playerCode, CurrencyType.CT_装备, dataId, 1);
        }
        if (backEquipId > 0) {
            Item.add(playerCode, CurrencyType.CT_装备, backEquipId, 1);
        }
        hero.setequip(pos, dataId);
        updateHero(playerCode, hero);

        return Result.Success;
    }

    public Result changeEquipFast(String playerCode, Hero hero) throws Exception {
        // 寻找最佳组合
        Collection<Currency> all = new PackageHandle().getItems(playerCode, CurrencyType.CT_装备);
        HashMap<EquipPosition, equipdata> best = new HashMap<>();
        for (Currency equip : all) {
            if (equip.getNumber() <= 0) {
                continue;
            }
            equipdata data = DataCenter.getData(equip.getDataId(), equipdata.class);
            EquipPosition position = EquipPosition.forNumber(data.getPosition());

            if (position == null) {
                continue;
            }

            if (!best.containsKey(position)) {
                best.put(position, data);
                continue;
            }
            equipdata bestdata = best.get(position);
            if (data.level() > bestdata.level()) {
                best.put(position, data);
            }
        }
        // 依次替换
        Set<Entry<EquipPosition, equipdata>> entrySet = best.entrySet();
        for (Entry<EquipPosition, equipdata> entry : entrySet) {
            EquipPosition pos = entry.getKey();
            equipdata data = entry.getValue();
            int backEquipId = hero.getequip(pos);
            if (backEquipId == data.getId()) {
                continue;
            }
            if (backEquipId > 0) {
                equipdata heroequip = DataCenter.getData(backEquipId, equipdata.class);
                if (heroequip.level() >= data.level()) {
                    continue;
                }
            }
            Item.minus(playerCode, CurrencyType.CT_装备, data.getId(), 1);
            if (backEquipId > 0) {
                Item.add(playerCode, CurrencyType.CT_装备, backEquipId, 1);
            }
            hero.setequip(pos, data.getId());
        }
        updateHero(playerCode, hero);

        return Result.Success;
    }

    public Collection<Hero> createHero(String playerCode, int dataId, long number, CCReason reason) {
        herodata data = DataCenter.getData(dataId, herodata.class);
        if (data == null) {
            logger.error("---------------------HeroHandle.createHero 武将数据不存在，herodataId：%d", dataId);
            throw new NullPointerException("武将数据不存在");
        }
        ArrayList<Hero> list = new ArrayList<>();
        try {
            if (Hero.lockHero(playerCode)) {
                for (int i = 0; i < number; i++) {
                    Hero hero = _createHero(playerCode, data, reason);
                    //招募武将记录
                    Runnable runnable = () -> {
                        boolean isRepeat = OpenServiceRushRankHandle
                                .updateHeroRanking(playerCode, hero.getDataId(), OpenServiceRushRankEnum.开服冲榜_武将比拼.getType());
                        //记录任务信息
                        if (isRepeat) {
                            OpenServiceRushRecord.recordFirstCompleteHeroTask(playerCode);
                        }
                    };
                    ThreadPoolManager.getInstance().execute(runnable);
                    if (hero != null) {
                        list.add(hero);
                    }
                }
                HeroPackPublisher.getInstance().publish(playerCode);
            }
        } catch (Exception e) {
        } finally {
            Hero.unlockHero(playerCode);
        }
        return list;
    }

    public Hero createHero(String playerCode, int dataId, CCReason reason) {
        herodata data = DataCenter.getData(dataId, herodata.class);
        if (data == null) {
            logger.error("---------------------HeroHandle.createHero 武将数据不存在，herodataId：%d", dataId);
            throw new NullPointerException("武将数据不存在");
        }
        try {
            if (Hero.lockHero(playerCode)) {
                Hero hero = _createHero(playerCode, data, reason);
                Runnable runnable = () -> {
                    HeroPackPublisher.getInstance().publish(playerCode);
                    //碎片合成武将记录
                    boolean isRepeat = OpenServiceRushRankHandle
                            .updateHeroRanking(playerCode, hero.getDataId(), OpenServiceRushRankEnum.开服冲榜_武将比拼.getType());
                    //记录任务信息
                    if (isRepeat) {
                        OpenServiceRushRecord.recordFirstCompleteHeroTask(playerCode);
                    }
                };
                ThreadPoolManager.getInstance().execute(runnable);
                return hero;
            }
        } catch (Exception e) {
        } finally {
            Hero.unlockHero(playerCode);
        }
        return null;
    }

    private Hero _createHero(String playerCode, herodata data, CCReason reason) throws RedisException {
        Hero hero = Hero.create(data, playerCode, reason);
        Runnable runnable = () -> TaskHandle.handle(playerCode, TaskType.统计型_武将_星级_个数, 1, hero.getStar());
        ThreadPoolManager.getInstance().execute(runnable);

        if (hero.getStar() >= 5) {
            // 发消息
            PlayerBean player = PlayerBean.get(playerCode);
            Runnable runnable1 = () -> new NotificationHandle().notifyChatInner(playerCode, GameString.招募获得5星武将(player.getName(), data.getName()));
            ThreadPoolManager.getInstance().execute(runnable1);
        }

        return hero;
    }

    // 碎片合成===========================================================================
//	public Currencies chipCompoundRewards(debris data, int num) {
//		Currencies rewards = new Currencies();
//		switch (data.getType()) {
//		case 1: {
//			rewards.add(Currency.create(CurrencyType.CT_武将, data.getHeroid(), num));
//		}
//			break;
//		case 2: {
//			for (int i = 0; i < num; i++) {
//				randomdrop _randomdrop = DataCenter.getData(data.getRandomid(), randomdrop.class);
//				Currency reward = new PackageHandle().randomCurrency(_randomdrop);
//				rewards.add(reward);
//			}
//		}
//			break;
//		}
//		return rewards;
//	}

    public Collection<Hero> chipCompound(String playerCode, debris data, int num) {
        ArrayList<Hero> list = new ArrayList<>();
        switch (data.getType()) {
            case 1: {
                for (int i = 0; i < num; i++) {
                    Hero hero = createHero(playerCode, data.getHeroid(), CCReason.碎片合成);
                    if (hero != null) {
                        list.add(hero);
                    }
                }
            }
            break;
            case 2: {
                for (int i = 0; i < num; i++) {
                    randomdrop _randomdrop = DataCenter.getData(data.getRandomid(), randomdrop.class);
                    Currency reward = new PackageHandle().randomCurrency(_randomdrop);
                    if (reward.getType().equals(CurrencyType.CT_武将)) {
                        list.addAll(createHero(playerCode, reward.getDataId(), reward.getNumber(), CCReason.碎片合成));
                    }
                }
            }
            break;
        }
        return list;
    }

    // 献祭===========================================================================

    /**
     * 武将献祭返还的材料
     */
    public Result getHeroAltarBack(String playerCode, Collection<String> heroCodes, ArrayList<Currency> back) {
        Map<String, Hero> heros = getFreeHeros(playerCode);
        Currencies temp = new Currencies();
        for (String code : heroCodes) {
            if (!heros.containsKey(code)) {
                return Result.AltarHeroForbid;// 选择的武将不能献祭
            }
            Hero hero = heros.get(code);
            //武将献祭，并返回材料
            temp.addAll(hero.trainAll());
            heroadvanced _advanced = DataCenter.getData(hero.advancedCode(), heroadvanced.class);
            if (_advanced == null) {
                throw new NullPointerException("playerCode:" + playerCode + "------hero.advancedCode():" + hero.advancedCode() + "------hero.getStage():" + hero.getStage());
            }

            Battle.battleLogger(1, "getHeroAltarBack_hero.advancedCode()::::" + hero.advancedCode());
            temp.addAll(Currency.create(_advanced.getDegenerationcost(), _advanced.getDegenerationid(), _advanced.getDegenerationnum()));
        }
        back.addAll(temp);
        return Result.Success;
    }

    public Collection<String> getHeroAltarQuick(String playerCode) {
        Set<String> set = new HashSet<>();
        Map<String, Hero> heros = getFreeHeros(playerCode);
        Set<Hero> star3heros = new HashSet<>();
        for (Hero hero : heros.values()) {
            if (hero.getStar() < 3) {
                set.add(hero.getCode());
            }
            if (hero.getStar() == 3) {
                star3heros.add(hero);
            }
        }
        int[] num = new int[6];
        for (Hero hero : star3heros) {
            herodata data = DataCenter.getData(hero.getDataId(), herodata.class);
            int power = data.getPower();
            if (num[power - 1] < 4) {
                num[power - 1]++;
                continue;
            }
            set.add(hero.getCode());

        }
        return set;
    }

    // 七星祭坛===========================================================================

    /**
     * 武将回退
     */
    public Result sevenStarRestore(String playerCode, String heroCode, TempleMessage.SevenStarRestoreResponse.Builder response) {
        Hero hero = getHero(playerCode, heroCode);
        if (hero == null) {
            return Result.HeroNotExists;// 武将不存在
        }
        heroadvanced _heroadvanced = DataCenter.getData(hero.advancedCode(), heroadvanced.class);
        if (_heroadvanced.getBackoff() <= 0) {
            return Result.TempleHeroCantRestore;// 不可回退
        }
        if (hero.isLock() || new FormatHandle().heroInFormat(playerCode, hero.getCode())) {
            return Result.TempleHeroCantRestore;// 不可回退
        }

        Currency cost = Currency.create(_heroadvanced.getDropcosttype(), _heroadvanced.getDropcostid(), _heroadvanced.getDropcostnum());
        try {
            new CurrencyHandle().cost(playerCode, CCReason.七星祭坛, cost);
        } catch (CurrencyNotEnoughException e) {
            return new Result(Result.CostFail, e.getType().getNumber(), e.getDataId());// 消费不足
        }

        //根据算法，自动算返回的武将和碎片
        Collection<Currency> rewards = getSevenStarRestoreInfo(hero);
        new CurrencyHandle().addCurrency(playerCode, CCReason.七星祭坛, rewards);

        HashMap<String, Hero> expendhero = new HashMap<>();
        expendhero.put(hero.getCode(), hero);
        Collection<Currency> back = expendBackDo(playerCode, expendhero, CCReason.七星祭坛);

        // 封装消息
        response.setHero(hero.getCode());
        response.addAllBack(new CurrencyHandle().packItems(rewards));
        response.addAllBack(new CurrencyHandle().packItems(back));

        return Result.Success;
    }

    //根据算法，自动算返回的武将和碎片
    public Collection<Currency> getSevenStarRestoreInfo(Hero hero) {
        List<Currency> list = new ArrayList<>();
        int dataId = hero.getDataId();//武将id

        //todo 获取所属势力
        herodata _herodata = DataCenter.getData(dataId, herodata.class);
        int power = _herodata.getPower();//所属势力
        int heroStar = hero.getStar();//当前星级

        HashMap<Integer, Integer> map_heroadvanceddata = new HashMap<>();//key武将星级，value武将id
        heroadvanceddata data = DataCenter.getData(dataId, heroadvanceddata.class);
        while (data != null) {
            int id = data.getId();
            int startop = data.getStartop();
            map_heroadvanceddata.put(startop, id);
            data = DataCenter.getData(data.getDegenerationid(), heroadvanceddata.class);
        }

        //todo 获取阵容的碎片id
        int debrisId = getPowerId(power);
        if (debrisId == 0) return list;//同阵营的5星碎片不存在

        //todo 获取5星的碎片id
        Integer hero_fiveStarId = map_heroadvanceddata.get(5);

        if (hero_fiveStarId == null || map_heroadvanceddata.size() == 0) return list;//5星碎片不存在或表没找到，出错返回空

        //todo 获取5-8星的 heroId_start 对应的 heroadvanced ,再根据升级所需要的材料进行回退
        for (Entry<Integer, Integer> entry : map_heroadvanceddata.entrySet()) {
            Integer heroId = entry.getValue();
            for (int star = 5; star < heroStar; star++) {
                heroadvanced _heroadvanced = DataCenter.getData(String.format("%d_%d", heroId, star), heroadvanced.class);
                if (_heroadvanced == null) continue;
                consume(_heroadvanced, list, hero_fiveStarId, debrisId);
            }
        }

        //还要把融掉的本体还回去
        list.add(Currency.create(CurrencyType.CT_碎片, hero_fiveStarId, 50));

        Collection<Currency> merge = Currency.merge(list);//合并

        return merge;
    }


    //每个星级的升级消耗
    public void consume(heroadvanced _heroadvanced, List<Currency> list, int hero_fiveStarId, int debrisId) {
        Currency reward = null;
        //升星需要的本体和6星武将和同阵营武将
        int[] conditiontype = _heroadvanced.getConditiontype();
        int[] cost2 = _heroadvanced.getCost2();
        int[] cost3 = _heroadvanced.getCost3();
        for (int i = 0; i < conditiontype.length; i++) {
            if (conditiontype[i] == -1) continue;

            if (conditiontype[i] == 1 && cost2[i] == 5) {//本体5星
                reward = Currency.create(CurrencyType.CT_碎片, hero_fiveStarId, cost3[i] * 50);
            }

            if (conditiontype[i] == 1 && cost2[i] == 6) {//本体6星
                //每个6星给4个五星碎片
                reward = Currency.create(CurrencyType.CT_碎片, debrisId, cost3[i] * 50 * 5);
            }

            if (conditiontype[i] == 2 && cost2[i] == 5) {//同阵容5星
                reward = Currency.create(CurrencyType.CT_碎片, debrisId, cost3[i] * 50);
            }

            if (conditiontype[i] == 2 && cost2[i] == 6) {//同阵容6星
                reward = Currency.create(CurrencyType.CT_碎片, debrisId, cost3[i] * 50 * 5);
            }

            if (conditiontype[i] == 3 && cost2[i] == 5) {//全阵营5星
                reward = Currency.create(CurrencyType.CT_碎片, 8015, cost3[i] * 50);
            }

            if (conditiontype[i] == 3 && cost2[i] == 6) {//全阵营6星
                reward = Currency.create(CurrencyType.CT_碎片, 8015, cost3[i] * 50 * 5);
            }

            if (reward != null) list.add(reward);
        }

    }

    //根据阵容返回阵容的碎片id
    public int getPowerId(int power) {
        int debrisId = 0;
        switch (power) {
            case 1:
                debrisId = 8002;
                break;
            case 2:
                debrisId = 8004;
                break;
            case 3:
                debrisId = 8006;
                break;
            case 4:
                debrisId = 8008;
                break;
            case 5:
                debrisId = 8010;
                break;
            case 6:
                debrisId = 8012;
                break;
        }
        return debrisId;
    }


    // 置换神殿===========================================================================

    /**
     * 神殿置换
     */
    public Result templeChange(String playerCode, String heroCode, Collection<String> expend, TempleMessage.TempleChangeResponse.Builder response, boolean isBackMagic) {
        Hero hero = getHero(playerCode, heroCode);
        if (hero == null) {
            return Result.HeroNotExists;// 武将不存在
        }
        heroadvanced _heroadvanced = DataCenter.getData(hero.advancedCode(), heroadvanced.class);
        if (_heroadvanced.getBarter() <= 0) {
            return Result.TempleHeroCantChange;// 不可置换
        }
        Map<String, Hero> heros = getFreeHeros(playerCode);
        HashMap<String, Hero> expendhero = new HashMap<>();
        int dataId = 0;
        for (String code : expend) {
            if (hero.getCode().equals(code)) {
                return Result.TempleHeroCantExpendSelf;// 不能吃自己
            }
            Hero expendHero = heros.get(code);
            if (expendHero == null) {
                return Result.TempleHeroCantChange;// 不可置换
            }
            if (dataId == 0) {
                dataId = expendHero.getDataId();
                if (hero.getDataId() / 100 == dataId / 100) {
                    return Result.TempleHeroCantChangeSame;// 不能置换成相同武将
                }
                heroadvanced _advanced = DataCenter.getData(expendHero.advancedCode(), heroadvanced.class);
                if (_advanced.getPassbarter() <= 0) {
                    return Result.TempleHeroCantChange;// 不可被置换
                }
                expendhero.put(expendHero.getCode(), expendHero);
            } else if (dataId != expendHero.getDataId()) {
                return Result.TempleHeroExpendSame;// 要选择一样的武将
            }
            expendhero.put(expendHero.getCode(), expendHero);
        }

        //本体的消耗数量（通过计算获取）
        HashMap<String, Integer> map = TempleHandle.getNum(hero);
        int num = map.get("num");
        if (expendhero.size() != num) {
            return Result.TempleHeroExpendNumber;// 置换武将数量不符
        }

        Currency cost = Currency.create(_heroadvanced.getBartercosttype(), _heroadvanced.getBartercostid(), _heroadvanced.getBartercostnum());
        if (cost != null) {  //需要消耗资源
            try {
                new CurrencyHandle().cost(playerCode, CCReason.置换神殿, cost);
            } catch (CurrencyNotEnoughException e) {
                return new Result(Result.CostFail, e.getType().getNumber(), e.getDataId());// 消费不足
            }
        }

        heroadvanceddata _heroadvanceddata = DataCenter.getData(dataId, heroadvanceddata.class);
        while (_heroadvanceddata != null && _heroadvanceddata.getStartop() < hero.getStar()) {
            dataId = _heroadvanceddata.getEvolutionid();
            _heroadvanceddata = DataCenter.getData(dataId, heroadvanceddata.class);
        }

        //返回左侧本体+碎片，判断玩家是否需要转换兵法或直接移植兵法
        Collection<Currency> benti = returnBenti(playerCode, hero, map, CCReason.置换神殿, isBackMagic);

        hero.setDataId(dataId);
        updateHero(playerCode, hero);

        //本体消耗返还
        Collection<Currency> back = expendBackDo(playerCode, expendhero, CCReason.置换神殿);
        if (benti != null) back.addAll(benti);

        // 封装消息
        response.setHero(getHeroSimple(playerCode, hero));
        response.addAllBack(new CurrencyHandle().packItems(back));

        return Result.Success;
    }

    //置换神殿
    private Collection<Currency> returnBenti(String playerCode, Hero hero, HashMap<String, Integer> map, CCReason reason, boolean isBackMagic) {
        Currencies back = new Currencies();
        ArrayList<String> list = new ArrayList<>();
        try {
            //todo 1.返还本体（全碎片）
            Integer dataId = map.get("dataId");
            Integer num = map.get("num");
//            Currency benti_ = Currency.create(CurrencyType.CT_武将, dataId, 1);
            Currency benti_suipian = Currency.create(CurrencyType.CT_碎片, dataId, (num ) * 50);
            back.add(benti_suipian);

            //todo 2.如果兵法不转移，分解成材料返回
            if (isBackMagic) {
                list.add(hero.getCode());
                Currencies reward = unfixArtOfWarAndCharm(playerCode, list);
                back.add(reward);
                hero.setMagicA(null);
                hero.setMagicB(null);
            }
            //返还
            new CurrencyHandle().addCurrency(playerCode, reason, back);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return back;
    }

    // 高级祭坛===========================================================================

    /**
     * 回退操作
     */
    public Result seniorAltarBack(String playerCode, String heroCode, TempleMessage.SeniorAltarBackResponse.Builder response) {
        Hero hero = getHero(playerCode, heroCode);
        if (hero == null) {
            return Result.HeroNotExists;// 武将不存在
        }
        heroadvanced _heroadvanced = DataCenter.getData(hero.advancedCode(), heroadvanced.class);
        if (_heroadvanced.getSeniorbackoff() <= 0) {
            return Result.TempleHeroCantBack;// 不可回退
        }

        Currencies back = new Currencies();
        ArrayList<Currency> backHero = new ArrayList<>();
        Result result = seniorAltarBackCurrency(playerCode, hero, back, backHero);
        if (!result.equals(Result.Success)) {
            return result;
        }
        if (getHerosSize(playerCode) + backHero.size() > getUpper(playerCode)) {
            return Result.HeroCountUpper;// 武将背包空余不足
        }

        Currency cost = Currency.create(_heroadvanced.getSeniordropcosttype(), _heroadvanced.getSeniordropcostid(), _heroadvanced.getSeniordropcostnum());
        try {
            new CurrencyHandle().cost(playerCode, CCReason.高级祭坛, cost);
        } catch (CurrencyNotEnoughException e) {
            return new Result(Result.CostFail, e.getType().getNumber(), e.getDataId());// 消费不足
        }

        for (Currency backHeroCurrency : backHero) {
            try {
                herodata _herodata = DataCenter.getData(backHeroCurrency.getDataId(), herodata.class);
                Hero.create(_herodata, (int) backHeroCurrency.getNumber(), playerCode, CCReason.高级祭坛);
            } catch (RedisException e) {
            }
        }

        // 武将预处理 保存
        updateHero(playerCode, hero);

        if (back.size() > 0) {
            new CurrencyHandle().addCurrency(playerCode, CCReason.高级祭坛, back);

            response.addAllBack(new CurrencyHandle().packItems(back));
        }
        response.addAllBack(new CurrencyHandle().packItems(backHero));
        response.setHero(getHeroSimple(playerCode, hero));

        return Result.Success;
    }

    /**
     * 回退返回的材料
     */
    public Result seniorAltarBackCurrency(String playerCode, Hero hero, Currencies back, ArrayList<Currency> backHero) {
        heroadvanced _heroadvanced = DataCenter.getData(hero.advancedCode(), heroadvanced.class);
        if (_heroadvanced.getSeniorbackoff() <= 0) {
            return Result.TempleHeroCantBack;// 不可回退
        }
        heroadvanceddata _heroadvanceddata = DataCenter.getData(hero.getDataId(), heroadvanceddata.class);
        int backId = _heroadvanceddata.getDegenerationid();
        heroadvanceddata _heroadvanceddataback = DataCenter.getData(backId, heroadvanceddata.class);
        herodata _herodataback = DataCenter.getData(backId, herodata.class);
        if (_herodataback == null || _heroadvanceddataback == null) {
            return Result.TempleHeroCantBack;// 不可回退
        }
        int starback = _heroadvanceddataback.getStartop();
        if (hero.getStar() <= starback) {
            return Result.DataError;// 数据错误
        }
        String advancedCode = String.format("%d_%d", backId, starback);
        heroadvanced _heroadvancedback = DataCenter.getData(advancedCode, heroadvanced.class);
        int levelUpBack = _heroadvancedback.getHerolvup();
        if (hero.getLevel() > levelUpBack) {
            // 培养消耗
            back.add(Hero.levelUpCost(levelUpBack, hero.getLevel()));
        }
        // 升星消耗
        if (hero.getStarUpCost().size() > 0) {
            for (int i = 0; i < hero.getStar() - starback && i < hero.getStarUpCost().size(); i++) {
                Currencies backHeros = hero.getStarUpCost().get(i);
                backHero.addAll(backHeros);
            }
        }

        // 武将预处理
        hero.setDataId(backId);
        hero.setStar(starback);
        if (hero.getLevel() > levelUpBack) {
            hero.setLevel(levelUpBack);
        }

        return Result.Success;
    }

    // 状态检查 红点======================================================================

    /**
     * 搜索武将身上可以提示的位置
     */
    public void checkTipTypeForHero(String playerCode, Hero hero) {
        // 装备
        equipdata[] bestDatas = new PackageHandle().getBestEquipInPack(playerCode);// 背包里最好的装备

        Collection<Integer> tips = checkTipTypeForHero(playerCode, hero, bestDatas);

        //推送红点
        new NotificationHandle().HeroEquipTipNotification(playerCode, hero.getCode(), tips);
    }

    private Collection<Integer> checkTipTypeForHero(String playerCode, Hero hero, equipdata[] bestDatas) {
        Set<TipType> set = new HashSet<>();
        int[] equips = hero.getEquips();
        for (int i = 0; i < equips.length; i++) {
            equipdata bestdata = bestDatas[i];
            if (bestdata == null) {
                continue;
            }
            if (equips[i] == 0) {
                set.add(forPosition(i));
                continue;
            }
            equipdata data = DataCenter.getData(equips[i], equipdata.class);
            if (data.level() < bestdata.level()) {
                set.add(forPosition(i));
//				break;
            }
        }
        // 升阶检测
        if (checkStageUp(playerCode, hero)) {
            set.add(TipType.武将_升级升阶);
        }

        ArrayList<Integer> list = new ArrayList<>();
        for (TipType tipType : set) {
            list.add(tipType.getNumber());
        }
        return list;
    }

    private TipType forPosition(int position) {
        switch (position) {
            default:
                return TipType.武将_装备_武器;
            case 1:
                return TipType.武将_装备_头盔;
            case 2:
                return TipType.武将_装备_战甲;
            case 3:
                return TipType.武将_装备_护腕;
        }
    }

    /**
     * 武将红点推送
     */
    public void heroTipNotification(String playerCode, Hero hero) {
        ArrayList<Hero> heros = new ArrayList<>(new FormatHandle().formatHeros(playerCode, FormatType.普通).values());
        boolean addHero = true;
        for (Hero h : heros) {
            if (h.getCode().equals(hero.getCode())) {
                addHero = false;
                continue;
            }
        }
        if (addHero) {
            heros.add(hero);
        }

        HeroMessage.HeroTipNotification.Builder notify = HeroMessage.HeroTipNotification.newBuilder();

        equipdata[] bestDatas = new PackageHandle().getBestEquipInPack(playerCode);// 背包里最好的装备
        for (Hero h : heros) {
            HeroMessage.HeroTip.Builder builder = HeroMessage.HeroTip.newBuilder();
            builder.setCode(h.getCode());
            builder.addAllTips(checkTipTypeForHero(playerCode, h, bestDatas));
            notify.addHerotips(builder);
        }
        MessageEmitterHandler.getInstance().send(playerCode, notify.build());
    }

    /**
     * 阵容里有红点提示的武将code列表
     */
    public Collection<String> checkHeroTipInFormat(String playerCode, FormatType formatType) {
        Set<String> set = new HashSet<>();
        Collection<Hero> formatheros = new FormatHandle().formatHeros(playerCode, formatType).values();
        equipdata[] bestDatas = new PackageHandle().getBestEquipInPack(playerCode);// 背包里最好的装备
        for (Hero hero : formatheros) {
            boolean tip = checkHeroTip(playerCode, hero, bestDatas);
            if (tip) {
                set.add(hero.getCode());
            }
        }

        return set;
    }

    public void updateHeroTip(String playerCode) {
        new TipHandle().updateTip(playerCode, TipType.武将_界面按钮, checkHeroTip(playerCode));
    }

    private boolean checkHeroTip(String playerCode) {
        // 上阵武将的红点
        Collection<Hero> heros = new FormatHandle().formatHeros(playerCode, FormatType.普通).values();
        equipdata[] bestDatas = new PackageHandle().getBestEquipInPack(playerCode);// 背包里最好的装备
        for (Hero hero : heros) {
            boolean tip = checkHeroTip(playerCode, hero, bestDatas);
            if (tip) {
                return true;
            }
        }
        return false;
    }

    private boolean checkHeroTip(String playerCode, Hero hero, equipdata[] bestDatas) {
        // 升阶检测
        if (checkStageUp(playerCode, hero)) {
            return true;
        }
        // 装备检测
        int[] equips = hero.getEquips();
        for (int i = 0; i < equips.length; i++) {
            equipdata bestdata = bestDatas[i];
            if (bestdata == null) {
                continue;
            }
            if (equips[i] == 0) {
                return true;
            }
            equipdata data = DataCenter.getData(equips[i], equipdata.class);
            if (data.level() < bestdata.level()) {
                return true;
            }
        }
        return false;
    }

    // 升阶检测
    private boolean checkStageUp(String playerCode, Hero hero) {
        herostagecost _herostagecost = DataCenter.getData(hero.getStage(), herostagecost.class);
        int levelUpper = _herostagecost.getCondition();
        if (hero.getLevel() < levelUpper) {
            // 升级检测
            if (checkLevelUp(playerCode, hero)) {
                return true;
            }
            return false;// 等级不够
        }
        herograde grade = DataCenter.getData(hero.getDataId(), herograde.class);
        Battle.battleLogger(1, "升阶检测 hero.getDataId()::::::::::::::::" + hero.getDataId() + ":::::::hero.getCode():::::::" + hero.getCode());
        int stagemax = grade.getStagemax();// 升阶上限
        if (hero.getStage() >= stagemax) {
            return false;// 升阶已满
        }
        Collection<Currency> cost = Currency.create(_herostagecost.getCosttype(), _herostagecost.getCostid(), _herostagecost.getCostnum());
        return new CurrencyHandle().costCheck(playerCode, cost);
    }

    // 升级检测
    private boolean checkLevelUp(String playerCode, Hero hero) {
        HeroHandle heroHandle = new HeroHandle();
        int levelUpper = heroHandle.levelUpper(hero, playerCode);
        if (hero.getLevel() >= levelUpper) {
            return false;// 等级已到最高
        }
        if (hero.getLevel() + 1 > levelUpper) {
            return false;// 升级次数超上限了
        }
        Collection<Currency> cost = heroHandle.levelUpCost(hero, 1);
        return new CurrencyHandle().costCheck(playerCode, cost);
    }

    //升阶条件是否满足提示
    public void showStageUpMsg(HeroMessage.HeroInfoResponse.Builder response, String playerCode, String code) {
        Hero hero = Hero.get(playerCode, code);
        herostagecost _herostagecost = DataCenter.getData(hero.getStage(), herostagecost.class);
        //升阶需判断背包中武将星级、等级、数量
        Map<String, Hero> all = Hero.all(playerCode);
        HashMap<String, Integer> map = checkHeroStageUp(_herostagecost, all, hero);
        //StageUpMsg
        HeroMessage.StageUpMsg.Builder builder = HeroMessage.StageUpMsg.newBuilder();
        builder.setHeroNum(map.get("needNumber"));        //需要满足的英雄个数
        builder.setLevelNum(map.get("needLevel"));        //需要满足的等级
        builder.setStarNum(map.get("starCondition"));    //需要满足的星级
        //是否满足进阶条件  0:满足显示绿色文字   1:不显示文字  2:达到要求等级的武将数量不满足 3:武将星级不满足
        builder.setIsAbleStageUp(0);//满足条件

        if (map.get("needNumber") == 0) {//不需要条件  不显示文字
            builder.setIsAbleStageUp(1);
        }

        if (map.get("heroNum") < map.get("needNumber")) {//达到等级要求的数量不满足  返回需要满足数量
            builder.setIsAbleStageUp(2);
        }

        if (map.get("heroStar") < map.get("starCondition")) {//达到星级要求的数量不满足  返回需要满足数量
            builder.setIsAbleStageUp(3);
        }

        response.setStageUpMsg(builder);
    }

    //兼容处理:表的英雄星级改变缓存也对应改变
    public static void changeStar(String playerCode) {
        String isStartChange = StartReset.get(playerCode);
        if (StringUtils.isEmpty(isStartChange)) {
            Battle.battleLogger(1, "--------------兼容处理:表的英雄星级改变缓存也对应改变---------------");
            Map<String, Hero> all = Hero.all(playerCode);
            Set<Entry<String, Hero>> entries = all.entrySet();
            for (Entry<String, Hero> heroEntry : entries) {
                Hero hero = heroEntry.getValue();
                Boolean isGone = true;
                int star = hero.getStar();
                int dataId = hero.getDataId();
                heroadvanced _heroadvanced = DataCenter.getData(hero.advancedCode(), heroadvanced.class);
                if (_heroadvanced == null) {
                    //先从低的找
                    if (isGone) {
                        for (int i = star; i > 0; i--) {
                            _heroadvanced = DataCenter.getData(String.format("%s_%s", dataId, i), heroadvanced.class);
                            if (_heroadvanced != null) {
                                hero.setStar(_heroadvanced.getStarlv());
                                Hero.set(playerCode, hero);
                                isGone = false;
                                break;
                            }
                        }
                    }
                    //低的没有就在表中往高星的找
                    if (isGone) {
                        for (int i = star; i < star + 5; i++) {
                            _heroadvanced = DataCenter.getData(String.format("%s_%s", dataId, i), heroadvanced.class);
                            if (_heroadvanced != null) {
                                hero.setStar(_heroadvanced.getStarlv());
                                Hero.set(playerCode, hero);
                                break;
                            }
                        }
                    }
                }
            }
            StartReset.set(playerCode, "1");
        }

    }

    //新版本竞技场 对战玩家的武将星级兼容
    public static void arenaChangeStar(PlayerMessage.PlayerInfo playerInfo) {
        Battle.battleLogger(1, "--------------兼容处理:新版本竞技场 对战玩家的武将星级兼容---------------");
        FormatHandle formatHandle = new FormatHandle();
        Collection<Hero> heroes = formatHandle.formatHeros(playerInfo.getPlayerCode(), FormatType.普通).values();
        for (Hero hero : heroes) {
            Boolean isGone = true;
            int star = hero.getStar();
            int dataId = hero.getDataId();
            heroadvanced _heroadvanced = DataCenter.getData(hero.advancedCode(), heroadvanced.class);
            if (_heroadvanced == null) {
                //先从低的找
                if (isGone) {
                    for (int i = star; i > 0; i--) {
                        _heroadvanced = DataCenter.getData(String.format("%s_%s", dataId, i), heroadvanced.class);
                        if (_heroadvanced != null) {
                            hero.setStar(_heroadvanced.getStarlv());
                            Hero.set(playerInfo.getPlayerCode(), hero);
                            isGone = false;
                            break;
                        }
                    }
                }
                //低的没有就在表中往高星的找
                if (isGone) {
                    for (int i = star; i < star + 5; i++) {
                        _heroadvanced = DataCenter.getData(String.format("%s_%s", dataId, i), heroadvanced.class);
                        if (_heroadvanced != null) {
                            hero.setStar(_heroadvanced.getStarlv());
                            Hero.set(playerInfo.getPlayerCode(), hero);
                            break;
                        }
                    }
                }
            }
        }
    }

    //兼容处理:用户武将首次登录根据等级升阶
    public static void changeStage(String playerCode) {
        try {
            String isChangeStage = StageReset.get(playerCode);
            if (StringUtils.isEmpty(isChangeStage)) {
                Battle.battleLogger(1, "--------------兼容处理:用户武将首次登录根据等级升阶---------------");
                //获取阶级  key 等级   value  阶级
                HashMap<Integer, Integer> mapForStage = new HashMap<>();
                ArrayList<Integer> arraryListForStage = new ArrayList<>();
                Map<String, herostagecost> allData = DataCenter.getAllData(herostagecost.class);
                for (herostagecost herostagecost : allData.values()) {
                    mapForStage.put(herostagecost.getCondition(), herostagecost.getId());
                    arraryListForStage.add(herostagecost.getCondition());
                }

                //等级排序
                Collections.sort(arraryListForStage);

                Map<String, Hero> all = Hero.all(playerCode);
                Set<Entry<String, Hero>> entries = all.entrySet();
                for (Entry<String, Hero> entry : entries) {
                    //大于120级的进行升阶
                    if (entry.getValue().getLevel() >= 120) {
                        Hero hero = entry.getValue();
                        int stage = entry.getValue().getStage();//当前阶级
                        int level = entry.getValue().getLevel();//当前等级
                        for (int i = 0; i < arraryListForStage.size(); i++) {
                            //重新设置阶级
                            if (level >= arraryListForStage.get(i)) {
                                hero.setStage(mapForStage.get(arraryListForStage.get(i)));
                                Hero.set(playerCode, hero);
                            }
                        }
                    }
                }

                //用户升级记录
                StageReset.set(playerCode, "1");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


    }


    //获取对应武将的最高星级
    public static int heroMaxStar(String playerCode, int heroDataId) {
        int maxStar = 0;
        try {
            String heroid_prefix = String.valueOf(heroDataId).substring(0, 5);//id前缀

            Map<String, Hero> all = Hero.all(playerCode);

            for (Hero hero : all.values()) {
                //如果
                if (String.valueOf(hero.getDataId()).startsWith(heroid_prefix)) {
                    maxStar = hero.getStar() > maxStar ? hero.getStar() : maxStar;
                }
            }

            TaskHandle.handle(playerCode, TaskType.指标型_武将星级_达到, maxStar);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return maxStar;
    }

    //重算战力
    public static void calculationPower(String playerCode) {
        try {
            String isBattleClear = BattleClear.get(playerCode);

            if (StringUtils.isEmpty(isBattleClear) || isBattleClear.equals("1") || isBattleClear.equals("2") || isBattleClear.equals("3")) {
                PlayTypeModule.create(playerCode);
                BattleClear.set(playerCode, "4");
                new BattleHandle().powerUpdate(playerCode);// 战力更新
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 阵营塔布阵页面获取上阵武将的总战力
     *
     * @param playerCode
     */
    public JSONArray getCampTowerAllPower(String playerCode, Map<Position, Hero> map, Format format, FormatType formatType, int isAfreshPower) {
        JSONArray jsonArray = new JSONArray();//  [{'code':'','power':''},{'code':'','power':''} ]
        try {
            BattleHandle battleHandle = new BattleHandle();
            //计算队伍的战力
            if (format.getIsAfreshPower() != isAfreshPower) {
                for (Entry<Position, Hero> entry : map.entrySet()) {
                    JSONObject heroJson = new JSONObject();
                    Hero hero = entry.getValue();
                    //计算单个武将的战力
                    long power = battleHandle.calculatePower(playerCode, hero, format);
                    heroJson.put(hero.getCode(), power);
                    jsonArray.add(heroJson);
                }
                format.setIsAfreshPower(1);
                Format.set(playerCode, formatType, format);
            } else {
                for (Entry<Position, Hero> entry : map.entrySet()) {
                    JSONObject heroJson = new JSONObject();
                    Hero hero = entry.getValue();
                    long power = hero.getPower();
                    heroJson.put(hero.getCode(), power);
                    jsonArray.add(heroJson);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return jsonArray;
    }

    /**
     * 阵营塔布阵保存获取队伍总战力
     *
     * @param heros
     * @param isChange
     * @return
     */
    public long getCampTowerAllPower(Collection<Hero> heros, Format format, String playerCode, int afreshPowerType, FormatType formatType, Boolean isChange) {
        Long allPower = 0l;
        try {
            //计算队伍的战力
            if (format.getIsAfreshPower() != afreshPowerType || isChange) {
                BattleHandle battleHandle = new BattleHandle();
                for (Hero hero : heros) {
                    allPower += battleHandle.calculatePower(playerCode, hero, format);
                }
                format.setIsAfreshPower(1);
                Format.set(playerCode, formatType, format);
            } else {
                for (Hero hero : heros) {
                    Long power = hero.getPower();
                    allPower += power;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return allPower;
    }


/**-------------------------------------------------- 兵符的方法 --------------------------------------------------**/
    /**
     * 献祭前将武将当前使用的兵法 100% 转换为对应的魂玉精华
     */
    public Currencies unfixArtOfWar(String playerCode, Collection<String> heroCodes) {
        Currencies temp = new Currencies();
        Iterator<String> iterator = heroCodes.iterator();
        while (iterator.hasNext()) {
            String heroCode = iterator.next();
            Hero hero = Hero.get(playerCode, heroCode);
            String magicA = hero.getMagicA();
            String magicB = hero.getMagicB();
            // 所有魂玉精华 的map
            Map<String, magicshop> hunYuMap = DataCenter.getAllData(magicshop.class);
            Set<Entry<String, magicshop>> entries = hunYuMap.entrySet();

            if (magicA != null) {
                //兵法槽A
                int hunYu1 = conversion(entries, magicA);
                temp.add(Currency.create(CurrencyType.CT_物品, 1010, hunYu1));
            }
            if (magicB != null) {
                //兵法槽B
                int hunYu2 = conversion(entries, magicB);
                temp.add(Currency.create(CurrencyType.CT_物品, 1010, hunYu2));
            }
        }
        return temp;
    }

    /**
     * 灵符 转换  魂玉精华
     */
    public int conversion(Set<Entry<String, magicshop>> entries, String magic) {
        int hunYuNumber = 0;
        Iterator<Entry<String, magicshop>> hunYuIterator = entries.iterator();
        while (hunYuIterator.hasNext()) {
            Entry<String, magicshop> hunYuEntry = hunYuIterator.next();
            // 兵法槽为空
            if (magic == null) {
                break;
            }
            // 兵法槽
            magicdata magicdata = DataCenter.getData(Integer.parseInt(magic), magicdata.class);
            if (magic != null && hunYuEntry.getValue().getShopid() == magicdata.getCostid()[0]) {
                int hunYu = hunYuEntry.getValue().getCostnum(); // 兵法商店中 灵符对应的魂玉数
                int lingFu = magicdata.getCostnum()[0]; //灵符数量
                int jingHua = magicdata.getCostnum()[1]; //兵法升级  所需的魂玉精华数量
                //currency = Currency.create(CurrencyType.CT_物品, hunYuEntry.getValue().getCostid(), hunYu * lingFu + jingHua);
                hunYuNumber = hunYu * lingFu + jingHua;
            }
        }
        return hunYuNumber;
    }

    /**
     * 魂玉 转换 魂玉精华
     */
    public Currencies unfixSoul(String playerCode, Collection<String> heroCodes) {
        Currencies temp = new Currencies();
        Iterator<String> iterator = heroCodes.iterator();
        while (iterator.hasNext()) {
            String heroCode = iterator.next();
            Hero hero = Hero.get(playerCode, heroCode);
            String soulA = hero.getSoulA();
            String soulB = hero.getSoulB();

            if (soulA != null) {
                Soul soul = Soul.get(playerCode, soulA);
                souldata soulAData = DataCenter.getData(soul.getDataId(), souldata.class);
                Currency currency = Currency.create(soulAData.getResolvetype(), soulAData.getResolveid(), soulAData.getResolvenum());
                temp.add(currency);
            }
            if (soulB != null) {
                Soul soul = Soul.get(playerCode, soulB);
                souldata soulBData = DataCenter.getData(soul.getDataId(), souldata.class);
                Currency currency = Currency.create(soulBData.getResolvetype(), soulBData.getResolveid(), soulBData.getResolvenum());
                temp.add(currency);
            }
        }
        return temp;
    }

    /**
     * 献祭前将武将当前使用的兵法 100% 转换为对应的魂玉精华 + 灵符
     */
    public Currencies unfixArtOfWarAndCharm(String playerCode, Collection<String> heroCodes) {
        Currencies temp = new Currencies();
        Iterator<String> iterator = heroCodes.iterator();
        Map<String, magicdata> magicDataMap = DataCenter.getAllData(magicdata.class);

        while (iterator.hasNext()) {
            String heroCode = iterator.next();
            Hero hero = Hero.get(playerCode, heroCode);
            String magicA = hero.getMagicA();
            String magicB = hero.getMagicB();
            // 100% 转换为对应的魂玉精华 + 灵符
            if (magicA != null) {
                //兵法槽A
                Currencies returnA = getReturn(magicA, magicDataMap);
                temp.addAll(returnA);
            }
            if (magicB != null) {
                //兵法槽B
                Currencies returnB = getReturn(magicB, magicDataMap);
                temp.addAll(returnB);
            }
        }
        return temp;
    }

    /**
     * 获取返回的魂玉精华 + 灵符
     **/
    private Currencies getReturn(String magic, Map<String, magicdata> magicDataMap) {
        Currencies temp = new Currencies();
        magicdata data = magicDataMap.get(magic);
        int id = data.getId();             //当前id
        int orginId = data.getCostid()[0];//原始id
        magicdata orginData = magicDataMap.get(String.valueOf(orginId));
        while (true) {
            //当前的id就是最低的级的那个id直接反一个灵符，结束
            if (id == orginId) {
                //本体
                temp.add(Currency.create(orginData.getCosttype()[0], orginData.getCostid()[0], orginData.getCostnum()[0]));
                break;
            }

            //返还
            temp.add(Currency.create(orginData.getCosttype()[0], orginData.getCostid()[0], orginData.getCostnum()[0]));
            if (orginData.getCosttype()[1] == 5) {
                temp.add(Currency.create(orginData.getCosttype()[1], orginData.getCostid()[1], orginData.getCostnum()[1]));
            }

            //判断下一个是不是当前id，是就返回并结束，否则继续循环
            orginData = magicDataMap.get(String.valueOf(orginData.getUpgradeid()));
            if (orginData.getId() == id) {
                temp.add(Currency.create(orginData.getCosttype(), orginData.getCostid(), orginData.getCostnum()));
                break;
            }

            if (orginData == null) {
                break;
            }
        }
        return temp;
    }

/**-------------------------------------------------- 兵符的方法 --------------------------------------------------**/


}
